package top.v5it.japi.ddd.core.dao.impl.wrapper;

import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.StrUtil;
import top.v5it.japi.ddd.core.dao.impl.Order;
import top.v5it.japi.ddd.core.dao.impl.Wrapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 排序包装
 *
 * @param <T> 实体类型
 * @param <W> 子类类型，用于方法链式调用
 * @date 2023/4/3
 */
public class OrderWrapper<T, W extends OrderWrapper<T, W>> extends Wrapper<T> {

    protected final W wrapper;
    private final List<Order> orders;

    @SuppressWarnings("unchecked")
    protected OrderWrapper(T entity) {
        super(entity);
        wrapper = (W) this;
        this.orders = new ArrayList<>();
    }

    /**
     * 按字段升序
     *
     * @param column 字段名
     * @return 当前实例
     */
    public W asc(String column) {
        Optional.ofNullable(column)
                .filter(StrUtil::isNotBlank).ifPresent(t -> addOrder(Order.asc(t)));
        return wrapper;
    }

    /**
     * 按字段升序
     *
     * @param columnFunc 字段的获取函数
     * @return 当前实例
     */
    public W asc(Func1<T, ?> columnFunc) {
        return this.asc(this.mapper(columnFunc));
    }

    /**
     * 按字段降序
     *
     * @param column 字段名
     * @return 当前实例
     */
    public W desc(String column) {
        Optional.ofNullable(column)
                .filter(StrUtil::isNotBlank).ifPresent(t -> addOrder(Order.desc(t)));
        return wrapper;
    }

    /**
     * 按字段降序
     *
     * @param columnFunc 字段的获取函数
     * @return 当前实例
     */
    public W desc(Func1<T, ?> columnFunc) {
        return this.desc(this.mapper(columnFunc));
    }

    /**
     * 添加排序
     *
     * @param order 排序对象
     */
    private void addOrder(Order order) {
        this.orders.add(order);
        final String collect = this.orders.stream()
                .map(Order::toString).collect(Collectors.joining(", "));
        addSegment("order", String.format("ORDER BY %s", collect));
    }
}
